﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.ExtensibleStorage;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;
using YJKRevitBase.WinForm;
using YRevitJig;
using YJKGeometryFuncs;

namespace YJKRevitBalc
{
	public class BalconyManager
	{
		public BalconyManager(ExternalCommandData cmdData)
		{
			Process currentProcess = Process.GetCurrentProcess();
            this.mWndRevit = new WindowHandle(currentProcess.MainWindowHandle);
			this.mUIApp = cmdData.Application;
			this.mUIDoc = this.mUIApp.ActiveUIDocument;
			this.mDoc = this.mUIDoc.Document;
			this.m_BalconyAtlevel = this.mDoc.ActiveView.GenLevel;
			this.m_uiDoc = this.mUIApp.ActiveUIDocument;
			this.m_drawJigCurve = new DrawJigCurve(cmdData);
		}

		public Result Create()
		{
			IListDate.WallTypeList = Helper.GetSystemFamilyElementList<WallType>(this.mDoc);
			IListDate.FloorTypeList = Helper.GetSystemFamilyElementList<FloorType>(this.mDoc);
			this.CreateLineType("红色交叉线", new Autodesk.Revit.DB.Color(byte.MaxValue, 0, 0));
			CreateBalconyForm createBalconyForm = new CreateBalconyForm();
			while (createBalconyForm.ShowDialog() == DialogResult.OK)
			{
				this.UpdateDlgData(false, ref createBalconyForm);
				this.m_bPickBalconyWidth = createBalconyForm.m_bPickBalconyWidth;
				this.m_nBalconyType = (int)createBalconyForm.m_BalconyType;
				this.m_lstTempELementId = new List<ElementId>();
				ElementSet newElements = new ElementSet();
				if (this.GetBalconyParam())
				{
					Transaction transaction = new Transaction(this.mDoc, "CreateBalcony");
					transaction.Start();
					try
					{
						this.CreateBalcony(newElements);
						transaction.Commit();
					}
					catch
					{
						transaction.RollBack();
					}
				}
				this.DeleteTempElements();
				this.RedrawDocument(this.mDoc);
			}
			this.EraseLineType("红色交叉线");
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		public Result Edit()
		{
			Group group = this.SelectGroup();
			if (group == null)
			{
				return Autodesk.Revit.UI.Result.Succeeded;
			}
			IListDate.WallTypeList = Helper.GetSystemFamilyElementList<WallType>(this.mDoc);
			IListDate.FloorTypeList = Helper.GetSystemFamilyElementList<FloorType>(this.mDoc);
			if (!this.ReadBalconyData(group))
			{
				YJKMessageBox.Show("阳台中的数据过时或数据被已破坏，请重新建立阳台！");
				return Autodesk.Revit.UI.Result.Succeeded;
			}
			CreateBalconyForm createBalconyForm = new CreateBalconyForm();
			createBalconyForm.m_bEditBalcony = true;
			this.UpdateDlgData(true, ref createBalconyForm);
			if (createBalconyForm.ShowDialog() != DialogResult.OK)
			{
				return Autodesk.Revit.UI.Result.Succeeded;
			}
			this.UpdateDlgData(false, ref createBalconyForm);
			this.UpdateBalconyParam();
			Transaction transaction = new Transaction(this.mDoc, "EditBalcony");
			transaction.Start();
			try
			{
				ElementSet newElements = new ElementSet();
				this.DeleteOldBalcony(group, ref newElements);
				this.CreateBalcony(newElements);
				transaction.Commit();
			}
			catch
			{
				transaction.RollBack();
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private void UpdateDlgData(bool bDataToDlg, ref CreateBalconyForm dlg)
		{
			if (bDataToDlg)
			{
				dlg.m_sWallType = this.m_BalconyWallType.Name;
				dlg.m_sFloorType = this.m_BalconyFloorType.Name;
				dlg.m_dBalconyWidth = AssistFunc.feetToMM(this.m_dBalconyWidth);
				dlg.m_dWallHeight = AssistFunc.feetToMM(this.m_dWallHeight);
				dlg.m_dLevelElevation = AssistFunc.feetToMM(this.m_dElevation);
				return;
			}
			this.m_BalconyWallType = (Helper.GetSelectType<WallType>(this.mDoc, dlg.m_sWallType) as WallType);
			this.m_BalconyFloorType = (Helper.GetSelectType<FloorType>(this.mDoc, dlg.m_sFloorType) as FloorType);
			this.m_dBalconyWidth = AssistFunc.mmToFeet(dlg.m_dBalconyWidth);
			this.m_dWallHeight = AssistFunc.mmToFeet(dlg.m_dWallHeight);
			this.m_dElevation = AssistFunc.mmToFeet(dlg.m_dLevelElevation);
		}

		private void UpdateBalconyParam()
		{
			double num = this.m_BalconyAtlevel.Elevation + this.m_dElevation;
			this.m_ptBalconyStart = new XYZ(this.m_ptBalconyStart.X, this.m_ptBalconyStart.Y, num);
			this.m_ptBalconyEnd = new XYZ(this.m_ptBalconyEnd.X, this.m_ptBalconyEnd.Y, num);
			this.m_ptBalconyDir = new XYZ(this.m_ptBalconyDir.X, this.m_ptBalconyDir.Y, num);
			if (this.m_nBalconyType == 0)
			{
				XYZ xyz = (this.m_ptBalconyDir - this.m_ptBalconyEnd).Normalize();
				this.m_ptBalconyDir = this.m_ptBalconyEnd + xyz * this.m_dBalconyWidth;
				return;
			}
			if (this.m_nBalconyType == 1)
			{
				XYZ xyz2 = (this.m_ptBalconyDir - this.m_ptBalconyEnd).Normalize();
				this.m_ptBalconyDir = this.m_ptBalconyEnd + xyz2 * this.m_dBalconyWidth;
				return;
			}
			if (this.m_nBalconyType == 2)
			{
				XYZ xyz3 = (this.m_ptBalconyDir - this.m_ptBalconyEnd).Normalize();
				this.m_ptBalconyDir = this.m_ptBalconyEnd + xyz3 * this.m_dBalconyWidth;
				return;
			}
			if (this.m_nBalconyType == 3)
			{
				XYZ xyz4 = (this.m_ptBalconyDir - this.m_ptBalconyStart).Normalize();
				this.m_ptBalconyDir = this.m_ptBalconyStart + xyz4 * this.m_dBalconyWidth;
				return;
			}
			if (this.m_nBalconyType == 4)
			{
				XYZ xyz5 = (this.m_ptBalconyDir - this.m_ptBalconyStart).Normalize();
				this.m_ptBalconyDir = this.m_ptBalconyStart + xyz5 * this.m_dBalconyWidth;
				return;
			}
			if (this.m_nBalconyType == 5)
			{
				XYZ xyz6 = (this.m_ptBalconyDir - this.m_ptBalconyStart).Normalize();
				this.m_ptBalconyDir = this.m_ptBalconyStart + xyz6 * this.m_dBalconyWidth;
			}
		}

		private bool GetBalconyParam()
		{
			if (this.m_nBalconyType == 0)
			{
				return this.GetBalconyParam_Normal();
			}
			if (this.m_nBalconyType == 1)
			{
				return this.GetBalconyParam_Normal();
			}
			if (this.m_nBalconyType == 2)
			{
				return this.GetBalconyParam_Corner();
			}
			if (this.m_nBalconyType == 3)
			{
				return this.GetBalconyParam_AlongWall();
			}
			if (this.m_nBalconyType == 4)
			{
				return this.GetBalconyParam_DrawBaseCurve();
			}
			return this.m_nBalconyType == 5 && this.GetBalconyParam_PickBaseCurve();
		}

		private bool GetBalconyParam_Normal()
		{
			Line line = null;
			this.m_ptPickLast = null;
			try
			{
				if (this.m_drawJigCurve.DrawJigCurveLine(ref line, ref this.m_ptPickLast, "请确定阳台起点", "请确定阳台终点") != null)
				{
					return false;
				}
			}
			catch (Exception)
			{
				return false;
			}
			if (line == null)
			{
				return false;
			}
			this.m_ptBalconyStart = line.GetEndPoint(0);
			this.m_ptBalconyEnd = line.GetEndPoint(1);
			if (this.m_ptBalconyStart.DistanceTo(this.m_ptBalconyEnd) < BalconyManager.precision)
			{
				YJKMessageBox.Show("阳台长度不能为零");
				return false;
			}
			this.DrawTempLine(this.m_ptBalconyStart, this.m_ptBalconyEnd);
			this.m_ptBalconyDir = this.PickPointByBase("请指定阳台方向或宽度", this.m_ptBalconyEnd);
			if (this.m_ptBalconyDir == null)
			{
				return false;
			}
			double num = this.m_BalconyAtlevel.Elevation + this.m_dElevation;
			this.m_ptBalconyStart = new XYZ(this.m_ptBalconyStart.X, this.m_ptBalconyStart.Y, num);
			this.m_ptBalconyEnd = new XYZ(this.m_ptBalconyEnd.X, this.m_ptBalconyEnd.Y, num);
			this.m_ptBalconyDir = new XYZ(this.m_ptBalconyDir.X, this.m_ptBalconyDir.Y, num);
			XYZ xyz = Geometry.CalculateFootPoint(this.m_ptBalconyStart, this.m_ptBalconyEnd, this.m_ptBalconyDir);
			XYZ xyz2 = this.m_ptBalconyDir - xyz;
			if (xyz2.GetLength() < BalconyManager.precision)
			{
				YJKMessageBox.Show("不能确定阳台方向");
				return false;
			}
			if (this.m_bPickBalconyWidth)
			{
				this.m_dBalconyWidth = xyz2.GetLength();
			}
			this.m_ptBalconyDir = this.m_ptBalconyEnd + xyz2.Normalize() * this.m_dBalconyWidth;
			this.m_idElementStart = new ElementId(0);
			this.m_idElementEnd = new ElementId(0);
			return true;
		}

		private bool GetBalconyParam_Corner()
		{
			Wall wall = null;
			Wall wall2 = null;
			if (!this.SelectWall("请在墙角第一段墙上确定阳台起点", ref wall, ref this.m_ptBalconyStart))
			{
				return false;
			}
			this.m_ptPickLast = this.m_ptBalconyStart;
			this.DrawCrossFlag(this.m_ptBalconyStart);
			if (!this.SelectWall("请在墙角第二段墙上确定阳台终点", ref wall2, ref this.m_ptBalconyEnd, this.m_ptPickLast))
			{
				return false;
			}
			if (wall.Id == wall2.Id)
			{
				YJKMessageBox.Show("不能选择同一段墙");
				return false;
			}
			if (this.TwoWallIntersect(wall, wall2) == null)
			{
				YJKMessageBox.Show("两墙没有交点");
				return false;
			}
			this.m_ptBalconyDir = this.PickPointByBase("以第二段墙为参考，指定阳台的方向或宽度", this.m_ptBalconyEnd);
			if (this.m_ptBalconyDir == null)
			{
				return false;
			}
			double num = this.m_BalconyAtlevel.Elevation + this.m_dElevation;
			XYZ wallEndPoint = this.GetWallEndPoint(wall2, 0);
			XYZ wallEndPoint2 = this.GetWallEndPoint(wall2, 1);
			XYZ ptStart = new XYZ(wallEndPoint.X, wallEndPoint.Y, num);
			XYZ ptEnd = new XYZ(wallEndPoint2.X, wallEndPoint2.Y, num);
			this.m_ptBalconyDir = new XYZ(this.m_ptBalconyDir.X, this.m_ptBalconyDir.Y, num);
			XYZ xyz = Geometry.CalculateFootPoint(ptStart, ptEnd, this.m_ptBalconyDir);
			XYZ xyz2 = this.m_ptBalconyDir - xyz;
			if (xyz2.GetLength() < BalconyManager.precision)
			{
				YJKMessageBox.Show("不能确定阳台方向");
				return false;
			}
			if (this.m_bPickBalconyWidth)
			{
				this.m_dBalconyWidth = xyz2.GetLength();
			}
			this.m_ptBalconyStart = new XYZ(this.m_ptBalconyStart.X, this.m_ptBalconyStart.Y, num);
			this.m_ptBalconyEnd = new XYZ(this.m_ptBalconyEnd.X, this.m_ptBalconyEnd.Y, num);
			this.m_ptBalconyDir = this.m_ptBalconyEnd + xyz2.Normalize() * this.m_dBalconyWidth;
			this.m_idElementStart = wall.Id;
			this.m_idElementEnd = wall2.Id;
			return true;
		}

		private bool GetBalconyParam_AlongWall()
		{
			List<Wall> list = this.SelectLinkWalls("请选择相连的墙");
			if (list == null || list.Count < 1)
			{
				return false;
			}
			Wall element = null;
			Wall wall = null;
			if (!this.SelectWall("请在选择的墙上指定阳台起点", ref element, ref this.m_ptBalconyStart))
			{
				return false;
			}
			if (!this.IsWallInList(element, list))
			{
				YJKMessageBox.Show("阳台起点不在选择的墙上");
				return false;
			}
			this.DrawCrossFlag(this.m_ptBalconyStart);
			if (!this.SelectWall("请在选择的墙上指定阳台终点", ref wall, ref this.m_ptBalconyEnd, this.m_ptBalconyStart))
			{
				return false;
			}
			if (!this.IsWallInList(wall, list))
			{
				YJKMessageBox.Show("阳台终点不在选择的墙上");
				return false;
			}
			if (this.m_ptBalconyStart.DistanceTo(this.m_ptBalconyEnd) < BalconyManager.precision)
			{
				YJKMessageBox.Show("阳台起点和终点距离太近。");
				return false;
			}
			this.m_ptBalconyDir = this.PickPointByBase("以阳台终点为参考，指定阳台的方向或宽度", this.m_ptBalconyEnd);
			if (this.m_ptBalconyDir == null)
			{
				return false;
			}
			XYZ wallEndPoint = this.GetWallEndPoint(wall, 0);
			XYZ wallEndPoint2 = this.GetWallEndPoint(wall, 1);
			this.m_ptBalconyDir = new XYZ(this.m_ptBalconyDir.X, this.m_ptBalconyDir.Y, wallEndPoint.Z);
			XYZ xyz = Geometry.CalculateFootPoint(wallEndPoint, wallEndPoint2, this.m_ptBalconyDir);
			XYZ xyz2 = this.m_ptBalconyDir - xyz;
			if (xyz2.GetLength() < BalconyManager.precision)
			{
				YJKMessageBox.Show("不能确定阳台方向");
				return false;
			}
			if (this.m_bPickBalconyWidth)
			{
				this.m_dBalconyWidth = xyz2.GetLength();
			}
			List<Curve> list2 = this.GetWallsBaseCurve(wall, this.m_ptBalconyEnd, this.m_ptBalconyStart);
			if (list2 == null || list2.Count < 1)
			{
				YJKMessageBox.Show("提取墙线失败");
				return false;
			}
			Curve curve = list2[0];
			XYZ xyzpoint = curve.Project(this.m_ptBalconyEnd).XYZPoint;
			list2[0] = this.SetCurveEnd(curve, xyzpoint, 0);
			curve = list2[list2.Count - 1];
			xyzpoint = curve.Project(this.m_ptBalconyStart).XYZPoint;
			list2[list2.Count - 1] = this.SetCurveEnd(curve, xyzpoint, 1);
			xyzpoint = list2[0].Project(this.m_ptBalconyEnd).XYZPoint;
			double dOffset = xyzpoint.DistanceTo(this.m_ptBalconyEnd);
			bool bOffsetLeft = this.IsPointAtCurveLeft(list2[0], this.m_ptBalconyEnd);
			list2 = this.OffsetCurves(list2, dOffset, bOffsetLeft);
			if (list2 == null)
			{
				YJKMessageBox.Show("阳台宽度值过大，不能在所选择的墙上创建。");
				return false;
			}
			this.MergeCurves(list2);
			double dElevation = this.m_BalconyAtlevel.Elevation + this.m_dElevation;
			list2 = this.SetCurvesElevation(list2, dElevation);
			this.m_ptBalconyStart = list2[0].GetEndPoint(0);
			this.m_ptBalconyDir = this.m_ptBalconyStart + xyz2.Normalize() * this.m_dBalconyWidth;
			this.m_lstBaseCurve = new List<ModelCurve>();
			Transaction transaction = new Transaction(this.mDoc);
			transaction.Start("CreateLines");
			Plane plane = RevitVersionFuncs.CreatePlanByNormalAndOrigin(XYZ.BasisZ, this.m_ptBalconyStart);
			SketchPlane sketchPlane = SketchPlane.Create(this.mDoc, plane);
			foreach (Curve curve2 in list2)
			{
				ModelCurve item = this.mDoc.Create.NewModelCurve(curve2, sketchPlane);
				this.m_lstBaseCurve.Add(item);
			}
			transaction.Commit();
			this.m_idElementStart = this.m_lstBaseCurve.First<ModelCurve>().Id;
			this.m_idElementEnd = this.m_lstBaseCurve.Last<ModelCurve>().Id;
			return true;
		}

		private bool GetBalconyParam_DrawBaseCurve()
		{
			List<Curve> list = null;
			try
			{
				list = this.DrawBaseCurve();
			}
			catch (Exception)
			{
				YJKMessageBox.Show("无法创建，请重新绘制!");
			}
			if (list == null || list.Count < 1)
			{
				return false;
			}
			Curve curve = list[list.Count - 1];
			XYZ hyendPoint = curve.GetEndPoint(0);
			XYZ hyendPoint2 = curve.GetEndPoint(1);
			XYZ xyz = this.PickPointByBase("以阳台基线终点为参考，指定阳台的方向或宽度", hyendPoint2);
			if (xyz == null)
			{
				return false;
			}
			XYZ xyz2 = Geometry.CalculateFootPoint(hyendPoint, hyendPoint2, xyz);
			XYZ xyz3 = xyz - xyz2;
			if (xyz3.GetLength() < BalconyManager.precision)
			{
				YJKMessageBox.Show("不能确定阳台方向");
				return false;
			}
			if (this.m_bPickBalconyWidth)
			{
				this.m_dBalconyWidth = xyz3.GetLength();
			}
			double dElevation = this.m_BalconyAtlevel.Elevation + this.m_dElevation;
			list = this.SetCurvesElevation(list, dElevation);
			list = this.ReverseCurves(list);
			this.m_ptBalconyStart = list[0].GetEndPoint(0);
			this.m_ptBalconyEnd = list[list.Count - 1].GetEndPoint(1);
			this.m_ptBalconyDir = this.m_ptBalconyStart + xyz3.Normalize() * this.m_dBalconyWidth;
			this.m_lstBaseCurve = new List<ModelCurve>();
			Transaction transaction = new Transaction(this.mDoc);
			transaction.Start("CreateLines");
			Plane plane = RevitVersionFuncs.CreatePlanByNormalAndOrigin(XYZ.BasisZ, this.m_ptBalconyStart);
			SketchPlane sketchPlane = SketchPlane.Create(this.mDoc, plane);
			foreach (Curve curve2 in list)
			{
				ModelCurve item = this.mDoc.Create.NewModelCurve(curve2, sketchPlane);
				this.m_lstBaseCurve.Add(item);
			}
			transaction.Commit();
			this.m_idElementStart = this.m_lstBaseCurve.First<ModelCurve>().Id;
			this.m_idElementEnd = this.m_lstBaseCurve.Last<ModelCurve>().Id;
			return true;
		}

		private bool GetBalconyParam_PickBaseCurve()
		{
			List<Curve> list = this.SelectBaseCurve();
			if (list == null || list.Count < 1)
			{
				return false;
			}
			Curve curve = list[0];
			XYZ hyendPoint = curve.GetEndPoint(0);
			XYZ hyendPoint2 = curve.GetEndPoint(1);
			XYZ xyz = this.PickPointByBase("以阳台基线终点为参考，指定阳台的方向或宽度", hyendPoint);
			if (xyz == null)
			{
				return false;
			}
			XYZ xyz2 = Geometry.CalculateFootPoint(hyendPoint, hyendPoint2, xyz);
			XYZ xyz3 = xyz - xyz2;
			if (xyz3.GetLength() < BalconyManager.precision)
			{
				YJKMessageBox.Show("不能确定阳台方向");
				return false;
			}
			if (this.m_bPickBalconyWidth)
			{
				this.m_dBalconyWidth = xyz3.GetLength();
			}
			double dElevation = this.m_BalconyAtlevel.Elevation + this.m_dElevation;
			list = this.SetCurvesElevation(list, dElevation);
			this.m_ptBalconyStart = list[0].GetEndPoint(0);
			this.m_ptBalconyEnd = list[list.Count - 1].GetEndPoint(1);
			this.m_ptBalconyDir = this.m_ptBalconyStart + xyz3.Normalize() * this.m_dBalconyWidth;
			this.m_lstBaseCurve = new List<ModelCurve>();
			Transaction transaction = new Transaction(this.mDoc);
			transaction.Start("CreateLines");
			Plane plane = RevitVersionFuncs.CreatePlanByNormalAndOrigin(XYZ.BasisZ, this.m_ptBalconyStart);
			SketchPlane sketchPlane = SketchPlane.Create(this.mDoc, plane);
			foreach (Curve curve2 in list)
			{
				ModelCurve item = this.mDoc.Create.NewModelCurve(curve2, sketchPlane);
				this.m_lstBaseCurve.Add(item);
			}
			transaction.Commit();
			this.m_idElementStart = this.m_lstBaseCurve.First<ModelCurve>().Id;
			this.m_idElementEnd = this.m_lstBaseCurve.Last<ModelCurve>().Id;
			return true;
		}

		private void CreateBalcony(ElementSet newElements)
		{
			if (this.m_nBalconyType == 0)
			{
				this.CreateBalcony_Normal(true, ref newElements);
			}
			else if (this.m_nBalconyType == 1)
			{
				this.CreateBalcony_Normal(false, ref newElements);
			}
			else if (this.m_nBalconyType == 2)
			{
				this.CreateBalcony_Corner(ref newElements);
			}
			else if (this.m_nBalconyType == 3)
			{
				this.CreateBalconyAlongCurves(ref newElements);
			}
			else if (this.m_nBalconyType == 4)
			{
				this.CreateBalconyAlongCurves(ref newElements);
			}
			else if (this.m_nBalconyType == 5)
			{
				this.CreateBalconyAlongCurves(ref newElements);
			}
			this.mDoc.Regenerate();
			Group group = this.CreateGroup(newElements);
			if (group != null)
			{
				this.WriteBalconyData(ref group);
			}
		}

		private void CreateBalcony_Normal(bool DrawBorder, ref ElementSet newElements)
		{
			double num = this.m_BalconyWallType.Width / 2.0;
			XYZ xyz = (this.m_ptBalconyEnd - this.m_ptBalconyStart).Normalize();
			XYZ xyz2 = (this.m_ptBalconyDir - this.m_ptBalconyEnd).Normalize();
			XYZ xyz3 = this.m_ptBalconyStart + xyz2 * this.m_dBalconyWidth;
			List<XYZ> list = new List<XYZ>();
			if (DrawBorder)
			{
				XYZ xyz4 = this.m_ptBalconyStart + xyz * num;
				XYZ xyz5 = this.m_ptBalconyEnd - xyz * num;
				XYZ xyz6 = xyz5 + xyz2 * (this.m_dBalconyWidth - num);
				XYZ xyz7 = xyz4 + xyz2 * (this.m_dBalconyWidth - num);
				list.Add(xyz4);
				list.Add(xyz7);
				list.Add(xyz6);
				list.Add(xyz5);
				if (Geometry.PointAtLineLeft(xyz6, xyz4, xyz7))
				{
					list.Reverse();
				}
				this.DrawWallByPoints(list, ref newElements);
			}
			else
			{
				XYZ item = this.m_ptBalconyStart + xyz2 * (this.m_dBalconyWidth - num);
				XYZ xyz8 = this.m_ptBalconyEnd + xyz2 * (this.m_dBalconyWidth - num);
				list.Add(item);
				list.Add(xyz8);
				if (!Geometry.PointAtLineLeft(xyz8, this.m_ptBalconyStart, this.m_ptBalconyEnd))
				{
					list.Reverse();
				}
				this.DrawWallByPoints(list, ref newElements);
			}
			CurveArray curveArray = new CurveArray();
			curveArray.Append(YJKLineEx.YJKGetBound(this.m_ptBalconyStart, this.m_ptBalconyEnd));
			curveArray.Append(YJKLineEx.YJKGetBound(this.m_ptBalconyEnd, this.m_ptBalconyDir));
			curveArray.Append(YJKLineEx.YJKGetBound(this.m_ptBalconyDir, xyz3));
			curveArray.Append(YJKLineEx.YJKGetBound(xyz3, this.m_ptBalconyStart));
			Floor floor = this.mDoc.Create.NewFloor(curveArray, this.m_BalconyFloorType, this.m_BalconyAtlevel, true);
			newElements.Insert(floor);
		}

		private void CreateBalcony_Corner(ref ElementSet newElements)
		{
			Wall wall = this.mDoc.GetElementById(this.m_idElementStart) as Wall;
			Wall wall2 = this.mDoc.GetElementById(this.m_idElementEnd) as Wall;
			double z = this.m_ptBalconyStart.Z;
			XYZ wallEndPoint = this.GetWallEndPoint(wall, 0);
			XYZ wallEndPoint2 = this.GetWallEndPoint(wall, 1);
			XYZ xyz = new XYZ(wallEndPoint.X, wallEndPoint.Y, z);
			XYZ xyz2 = new XYZ(wallEndPoint2.X, wallEndPoint2.Y, z);
			XYZ wallEndPoint3 = this.GetWallEndPoint(wall2, 0);
			XYZ wallEndPoint4 = this.GetWallEndPoint(wall2, 1);
			XYZ xyz3 = new XYZ(wallEndPoint3.X, wallEndPoint3.Y, z);
			XYZ xyz4 = new XYZ(wallEndPoint4.X, wallEndPoint4.Y, z);
			XYZ xyz5 = this.TwoWallIntersect(wall, wall2);
			XYZ xyz6 = new XYZ(xyz5.X, xyz5.Y, z);
			XYZ xyz7 = (xyz.DistanceTo(xyz6) < xyz2.DistanceTo(xyz6)) ? (xyz - xyz2) : (xyz2 - xyz);
			XYZ xyz8 = (xyz3.DistanceTo(xyz6) < xyz4.DistanceTo(xyz6)) ? (xyz3 - xyz4) : (xyz4 - xyz3);
			XYZ xyz9 = this.ExtenTwoLineIntersect(this.m_ptBalconyStart, this.m_ptBalconyStart + xyz7, this.m_ptBalconyEnd, this.m_ptBalconyEnd + xyz8);
			XYZ xyz10 = this.m_ptBalconyDir - this.m_ptBalconyEnd;
			XYZ xyz11;
			if (xyz10.AngleOnPlaneTo(xyz8, XYZ.BasisZ) < Math.PI)
			{
				xyz11 = Geometry.RotateTo(xyz7, Math.PI*.5, XYZ.BasisZ);
			}
			else
			{
				xyz11 = Geometry.RotateTo(xyz7, -Math.PI*.5, XYZ.BasisZ);
			}
			XYZ xyz12 = this.m_ptBalconyStart + xyz11.Normalize() * this.m_dBalconyWidth;
			XYZ xyz13 = this.ExtenTwoLineIntersect(xyz12, xyz12 + xyz7, this.m_ptBalconyDir, this.m_ptBalconyDir + xyz8);
			double num = this.m_BalconyWallType.Width / 2.0;
			List<XYZ> list = new List<XYZ>();
			if (xyz7.AngleTo(xyz13 - xyz12) <= 1.0 && xyz8.AngleTo(xyz13 - this.m_ptBalconyDir) <= 1.0)
			{
				XYZ xyz14 = this.m_ptBalconyStart + xyz7.Normalize() * num;
				XYZ xyz15 = xyz14 + xyz11.Normalize() * (this.m_dBalconyWidth - num);
				XYZ xyz16 = this.m_ptBalconyEnd + xyz8.Normalize() * num;
				XYZ xyz17 = xyz16 + xyz10.Normalize() * (this.m_dBalconyWidth - num);
				XYZ xyz18 = this.ExtenTwoLineIntersect(xyz15, xyz15 + xyz7, xyz17, xyz17 + xyz8);
				list.Add(xyz14);
				list.Add(xyz15);
				list.Add(xyz18);
				list.Add(xyz17);
				list.Add(xyz16);
				if (Geometry.PointAtLineLeft(xyz18, xyz14, xyz15))
				{
					list.Reverse();
				}
				this.DrawWallByPoints(list, ref newElements);
				CurveArray curveArray = new CurveArray();
				curveArray.Append(YJKLineEx.YJKGetBound(this.m_ptBalconyStart, xyz9));
				curveArray.Append(YJKLineEx.YJKGetBound(xyz9, this.m_ptBalconyEnd));
				curveArray.Append(YJKLineEx.YJKGetBound(this.m_ptBalconyEnd, this.m_ptBalconyDir));
				curveArray.Append(YJKLineEx.YJKGetBound(this.m_ptBalconyDir, xyz13));
				curveArray.Append(YJKLineEx.YJKGetBound(xyz13, xyz12));
				curveArray.Append(YJKLineEx.YJKGetBound(xyz12, this.m_ptBalconyStart));
				Floor floor = this.mDoc.Create.NewFloor(curveArray, this.m_BalconyFloorType, this.m_BalconyAtlevel, true);
				newElements.Insert(floor);
				return;
			}
			if (MessageBox.Show("阳台起点或终点到墙角距离小于阳台宽，是否继续？", "创建阳台", MessageBoxButtons.OKCancel) != DialogResult.OK)
			{
				throw new Exception("创建阳台被取消。");
			}
			XYZ xyz19 = this.ExtenTwoLineIntersect(this.m_ptBalconyStart, this.m_ptBalconyStart + xyz11, this.m_ptBalconyEnd, this.m_ptBalconyEnd + xyz10);
			XYZ xyz20 = this.m_ptBalconyStart + xyz7.Normalize() * num;
			XYZ xyz21 = xyz20 + xyz11.Normalize() * (xyz19.DistanceTo(this.m_ptBalconyStart) - num);
			XYZ xyz22 = this.m_ptBalconyEnd + xyz8.Normalize() * num;
			list.Add(xyz20);
			list.Add(xyz21);
			list.Add(xyz22);
			if (Geometry.PointAtLineLeft(xyz22, xyz20, xyz21))
			{
				list.Reverse();
			}
			this.DrawWallByPoints(list, ref newElements);
			CurveArray curveArray2 = new CurveArray();
			curveArray2.Append(YJKLineEx.YJKGetBound(this.m_ptBalconyStart, xyz19));
			curveArray2.Append(YJKLineEx.YJKGetBound(xyz19, this.m_ptBalconyEnd));
			curveArray2.Append(YJKLineEx.YJKGetBound(this.m_ptBalconyEnd, xyz9));
			curveArray2.Append(YJKLineEx.YJKGetBound(xyz9, this.m_ptBalconyStart));
			Floor floor2 = this.mDoc.Create.NewFloor(curveArray2, this.m_BalconyFloorType, this.m_BalconyAtlevel, true);
			newElements.Insert(floor2);
		}

		private void CreateBalconyAlongCurves(ref ElementSet newElements)
		{
			List<Curve> balconyBaseCurve = this.GetBalconyBaseCurve();
			if (balconyBaseCurve == null || balconyBaseCurve.Count < 1)
			{
				YJKMessageBox.Show("提取阳台基线失败！");
				throw new Exception("Command breaked");
			}
			bool flag = this.IsPointAtCurveLeft(balconyBaseCurve[0], this.m_ptBalconyDir);
			List<Curve> list = this.OffsetCurves(balconyBaseCurve, this.m_dBalconyWidth, flag);
			if (list == null)
			{
				YJKMessageBox.Show("阳台宽度值过大，不能创建阳台。");
				throw new Exception("Command breaked");
			}
			XYZ hyendPoint = balconyBaseCurve[0].GetEndPoint(0);
			XYZ hyendPoint2 = list[0].GetEndPoint(0);
			Line item = YJKLineEx.YJKGetBound(hyendPoint, hyendPoint2);
			list.Insert(0, item);
			XYZ hyendPoint3 = balconyBaseCurve[balconyBaseCurve.Count - 1].GetEndPoint(1);
			Line item2 = YJKLineEx.YJKGetBound(list[list.Count - 1].GetEndPoint(1), hyendPoint3);
			list.Add(item2);
			double dOffset = this.m_BalconyWallType.Width / 2.0;
			List<Curve> list2 = this.OffsetCurves(list, dOffset, !flag);
			if (list2 == null)
			{
				YJKMessageBox.Show("阳台宽度值过大，不能创建阳台。");
				throw new Exception("Command breaked");
			}
			bool flip = Geometry.PointAtLineLeft(list2[1].GetEndPoint(1), hyendPoint, hyendPoint2);
			foreach (Curve curve in list2)
			{
				Wall wall = RevitVersionFuncs.NewWall(this.mDoc, curve, this.m_BalconyWallType, this.m_BalconyAtlevel, this.m_dWallHeight, this.m_dElevation, flip, true);
				newElements.Insert(wall);
			}
			CurveArray curveArray = new CurveArray();
			foreach (Curve curve2 in list)
			{
				curveArray.Append(curve2);
			}
			foreach (Curve curve3 in this.ReverseCurves(balconyBaseCurve))
			{
				curveArray.Append(curve3);
			}
			Floor floor = this.mDoc.Create.NewFloor(curveArray, this.m_BalconyFloorType, this.m_BalconyAtlevel, true);
			newElements.Insert(floor);
			if (newElements.Size > 0)
			{
				foreach (ModelCurve modelCurve in this.m_lstBaseCurve)
				{
					newElements.Insert(modelCurve);
				}
			}
		}

		private List<Curve> SelectBaseCurve()
		{
			List<Curve> list = new List<Curve>();
			try
			{
				RevitVersionFuncs.ClearSelection(this.mUIDoc.Selection);
				foreach (Reference reference in this.mUIDoc.Selection.PickObjects((Autodesk.Revit.UI.Selection.ObjectType)1, new BalconyManager.CurveFilter(), "请选择模型线或详图线作为阳台基线"))
				{
					LocationCurve locationCurve = this.mDoc.GetElement(reference).Location as LocationCurve;
					if (locationCurve.Curve != null)
					{
						list.Add(locationCurve.Curve);
					}
				}
			}
			catch
			{
				return null;
			}
			list = this.SetCurvesElevation(list, 0.0);
			if (list.Count == 0)
			{
				return null;
			}
			if (list.Count == 1)
			{
				return list;
			}
			List<Curve> list2 = new List<Curve>();
			List<int> list3 = new List<int>();
			for (int i = 0; i < list.Count; i++)
			{
				Curve curve = list[i];
				List<Curve> list4 = new List<Curve>();
				List<Curve> list5 = new List<Curve>();
				for (int j = 0; j < list.Count; j++)
				{
					if (i != j)
					{
						Curve curve2 = list[j];
						IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
                        if ((int)curve.Intersect(curve2, out intersectionResultArray) == 8 && intersectionResultArray != null && !intersectionResultArray.IsEmpty)
						{
							XYZ xyzpoint = intersectionResultArray.get_Item(0).XYZPoint;
							if (xyzpoint.DistanceTo(curve.GetEndPoint(0)) < BalconyManager.precision)
							{
								list4.Add(curve2);
							}
							else if (xyzpoint.DistanceTo(curve.GetEndPoint(1)) < BalconyManager.precision)
							{
								list5.Add(curve2);
							}
						}
					}
				}
				if (list4.Count > 1 || list5.Count > 1)
				{
					YJKMessageBox.Show("选择的基线有分叉，不能布置阳台");
					return null;
				}
				if (list4.Count < 1 && list5.Count < 1)
				{
					YJKMessageBox.Show("选择的基线有断开，不能布置阳台");
					return null;
				}
				if (list4.Count == 0 && list5.Count == 1)
				{
					list2.Add(curve);
					list3.Add(1);
				}
				if (list4.Count == 1 && list5.Count == 0)
				{
					list2.Add(curve);
					list3.Add(0);
				}
			}
			if (list2.Count != 2)
			{
				YJKMessageBox.Show("不能确定基线起点和终点，不能布置阳台");
				return null;
			}
			List<Curve> list6 = this.FindLinkCurves(list2[0], list3[0], list);
			if (list6 != null && list6.Count > 0)
			{
				this.MergeCurves(list6);
			}
			return list6;
		}

		private List<Curve> DrawBaseCurve()
		{
			List<Curve> list = new List<Curve>();
			List<ModelCurve> list2 = new List<ModelCurve>();
			try
			{
				Polyline polyline = new Polyline(this.mWndRevit, this.mUIDoc.Application);
				polyline.DrawPolylines("请绘制阳台基线");
				polyline.GetCurves(ref list);
				polyline.GetCurves(ref list2);
			}
			catch
			{
				return null;
			}
			if (list.Count == 0)
			{
				return null;
			}
			foreach (ModelCurve modelCurve in list2)
			{
				this.m_lstTempELementId.Add(modelCurve.Id);
			}
			this.MergeCurves(list);
			return list;
		}

		private List<Curve> GetBalconyBaseCurve()
		{
			if (this.m_idElementStart == null || this.m_idElementEnd == null)
			{
				return null;
			}
			if (this.m_lstBaseCurve == null || this.m_lstBaseCurve.Count < 1)
			{
				return null;
			}
			ModelCurve modelCurve = null;
			List<Curve> list = new List<Curve>();
			foreach (ModelCurve modelCurve2 in this.m_lstBaseCurve)
			{
				if (modelCurve2.Id == this.m_idElementStart)
				{
					modelCurve = modelCurve2;
				}
				list.Add(modelCurve2.GeometryCurve);
			}
			if (modelCurve == null)
			{
				return null;
			}
			return this.FindLinkCurves(modelCurve.GeometryCurve, 1, list);
		}

		private List<Curve> GetWallsBaseCurve(Wall startWall, XYZ ptStart, XYZ ptEnd)
		{
			List<Wall> lstAllWall = (from w in new FilteredElementCollector(this.mDoc, this.mDoc.ActiveView.Id).OfClass(typeof(Wall))
			select w as Wall).ToList<Wall>();
			List<Wall> lstWall = this.FindLinkWalls(startWall, 0, lstAllWall);
			List<Wall> wallsUntilPoint = this.GetWallsUntilPoint(lstWall, ptEnd);
			if (wallsUntilPoint != null && wallsUntilPoint.Count > 0)
			{
				return this.GetBaseCurveAlongWalls(wallsUntilPoint, ptStart, ptEnd);
			}
			List<Wall> lstWall2 = this.FindLinkWalls(startWall, 1, lstAllWall);
			wallsUntilPoint = this.GetWallsUntilPoint(lstWall2, ptEnd);
			if (wallsUntilPoint != null && wallsUntilPoint.Count > 0)
			{
				return this.GetBaseCurveAlongWalls(wallsUntilPoint, ptStart, ptEnd);
			}
			return null;
		}

		private List<Curve> GetBaseCurveAlongWalls(List<Wall> lstWall, XYZ ptStart, XYZ ptEnd)
		{
			LocationCurve locationCurve = lstWall[0].Location as LocationCurve;
			XYZ hyendPoint = locationCurve.Curve.GetEndPoint(0);
			XYZ hyendPoint2 = locationCurve.Curve.GetEndPoint(1);
			XYZ ptStartBase = hyendPoint;
			if (lstWall.Count == 1)
			{
				XYZ xyz = hyendPoint2 - hyendPoint;
				XYZ xyz2 = ptEnd - ptStart;
				if (xyz.AngleTo(xyz2) > Math.PI*.5)
				{
					ptStartBase = hyendPoint2;
				}
			}
			else
			{
				XYZ xyz3 = this.TwoWallIntersect(lstWall[0], lstWall[1]);
				if (hyendPoint.DistanceTo(xyz3) < hyendPoint2.DistanceTo(xyz3))
				{
					ptStartBase = hyendPoint2;
				}
			}
			List<Curve> list = new List<Curve>();
			Curve curve = this.ReBuildCurve(locationCurve.Curve, ptStartBase);
			list.Add(curve);
			ptStartBase = curve.GetEndPoint(1);
			for (int i = 1; i < lstWall.Count; i++)
			{
				locationCurve = (lstWall[i].Location as LocationCurve);
				curve = this.ReBuildCurve(locationCurve.Curve, ptStartBase);
				list.Add(curve);
				ptStartBase = curve.GetEndPoint(1);
			}
			return list;
		}

		private List<Wall> GetWallsUntilPoint(List<Wall> lstWall, XYZ ptEnd)
		{
			int num = -1;
			for (int i = 0; i < lstWall.Count; i++)
			{
				if (this.IsPointOnWall(ptEnd, lstWall[i]))
				{
					num = i;
					break;
				}
			}
			if (num < 0)
			{
				return null;
			}
			List<Wall> list = new List<Wall>();
			for (int j = 0; j <= num; j++)
			{
				list.Add(lstWall[j]);
			}
			return list;
		}

		private List<Wall> FindLinkWalls(Wall startWall, int nEndIndex, List<Wall> lstAllWall)
		{
			List<Wall> list = new List<Wall>();
			list.Add(startWall);
			XYZ xyz = this.GetWallEndPoint(startWall, nEndIndex);
			Wall wall = this.FindLinkWall(startWall, nEndIndex, lstAllWall);
			while (wall != null && !this.IsWallInList(wall, list))
			{
				list.Add(wall);
				XYZ wallEndPoint = this.GetWallEndPoint(wall, 0);
				XYZ wallEndPoint2 = this.GetWallEndPoint(wall, 1);
				if (wallEndPoint.DistanceTo(xyz) < wallEndPoint2.DistanceTo(xyz))
				{
					xyz = wallEndPoint2;
					wall = this.FindLinkWall(wall, 1, lstAllWall);
				}
				else
				{
					xyz = wallEndPoint;
					wall = this.FindLinkWall(wall, 0, lstAllWall);
				}
			}
			return list;
		}

		private Wall FindLinkWall(Wall startWall, int nEndIndex, List<Wall> lstWall)
		{
			XYZ wallEndPoint = this.GetWallEndPoint(startWall, nEndIndex);
			foreach (Wall wall in lstWall)
			{
				if (!(wall.Id == startWall.Id))
				{
					XYZ xyz = this.TwoWallIntersect(startWall, wall);
					if (xyz != null && wallEndPoint.DistanceTo(xyz) < BalconyManager.precision)
					{
						return wall;
					}
				}
			}
			return null;
		}

		private List<Curve> FindLinkCurves(Curve startCurve, int nEndIndex, List<Curve> lstAllCurve)
		{
			List<Curve> list = new List<Curve>();
			list.Add(startCurve);
			XYZ xyz = startCurve.GetEndPoint(nEndIndex);
			Curve curve = this.FindLinkCurve(startCurve, nEndIndex, lstAllCurve);
			while (curve != null)
			{
				list.Add(curve);
				XYZ hyendPoint = curve.GetEndPoint(0);
				XYZ hyendPoint2 = curve.GetEndPoint(1);
				if (hyendPoint.DistanceTo(xyz) < hyendPoint2.DistanceTo(xyz))
				{
					xyz = hyendPoint2;
					curve = this.FindLinkCurve(curve, 1, lstAllCurve);
				}
				else
				{
					xyz = hyendPoint;
					curve = this.FindLinkCurve(curve, 0, lstAllCurve);
				}
			}
			return list;
		}

		private Curve FindLinkCurve(Curve startCurve, int nEndIndex, List<Curve> lstCurve)
		{
			XYZ hyendPoint = startCurve.GetEndPoint(nEndIndex);
			foreach (Curve curve in lstCurve)
			{
				if (!this.TwoCurveEquil(startCurve, curve))
				{
					XYZ xyz = this.TwoCurveIntersect(startCurve, curve);
					if (xyz != null && hyendPoint.DistanceTo(xyz) < BalconyManager.precision)
					{
						return curve;
					}
				}
			}
			return null;
		}

		private Curve SetCurveEnd(Curve oldCurve, XYZ ptNewEnd, int nEndIndex)
		{
			XYZ hyendPoint = oldCurve.GetEndPoint(0);
			XYZ hyendPoint2 = oldCurve.GetEndPoint(1);
			Curve result = null;
			if (oldCurve.GetType() == typeof(Line))
			{
				if (nEndIndex == 0)
				{
					result = YJKLineEx.YJKGetBound(ptNewEnd, hyendPoint2);
				}
				else
				{
					result = YJKLineEx.YJKGetBound(hyendPoint, ptNewEnd);
				}
			}
			else if (oldCurve.GetType() == typeof(Arc))
			{
				Arc arc = oldCurve as Arc;
				XYZ center = arc.Center;
				Line line = YJKLineEx.YJKGetBound(center, ptNewEnd);
                bool flag = (int)arc.Intersect(line) == 8;
				if (nEndIndex == 0)
				{
					if (flag)
					{
						XYZ radianPnt = Geometry.CalculatMidPoint(ptNewEnd, hyendPoint2, center, arc.Normal);
						result = this.mUIApp.Application.CreatYJKArc(ptNewEnd, hyendPoint2, radianPnt);
					}
					else
					{
						result = this.mUIApp.Application.CreatYJKArc(ptNewEnd, hyendPoint2, hyendPoint);
					}
				}
				else if (flag)
				{
					XYZ radianPnt2 = Geometry.CalculatMidPoint(hyendPoint, ptNewEnd, center, arc.Normal);
					result = this.mUIApp.Application.CreatYJKArc(hyendPoint, ptNewEnd, radianPnt2);
				}
				else
				{
					result = this.mUIApp.Application.CreatYJKArc(hyendPoint, ptNewEnd, hyendPoint2);
				}
			}
			return result;
		}

		private Curve ReBuildCurve(Curve oldCurve, XYZ ptStartBase)
		{
			XYZ xyz = oldCurve.GetEndPoint(0);
			XYZ xyz2 = oldCurve.GetEndPoint(1);
			if (xyz.DistanceTo(ptStartBase) > xyz2.DistanceTo(ptStartBase))
			{
				XYZ xyz3 = xyz;
				xyz = xyz2;
				xyz2 = xyz3;
			}
			Curve result = null;
			if (oldCurve.GetType() == typeof(Line))
			{
				result = YJKLineEx.YJKGetBound(xyz, xyz2);
			}
			else if (oldCurve.GetType() == typeof(Arc))
			{
				XYZ radianPnt = Geometry.CalculatMidPoint(oldCurve as Arc);
				result = this.mUIApp.Application.CreatYJKArc(xyz, xyz2, radianPnt);
			}
			return result;
		}

		private List<Curve> SetCurvesElevation(List<Curve> lstOldCurve, double dElevation)
		{
			List<Curve> list = new List<Curve>();
			foreach (Curve oldCurve in lstOldCurve)
			{
				Curve item = this.SetCurveElevation(oldCurve, dElevation);
				list.Add(item);
			}
			return list;
		}

		private Curve SetCurveElevation(Curve oldCurve, double dElevation)
		{
			Curve result = null;
			XYZ hyendPoint = oldCurve.GetEndPoint(0);
			XYZ hyendPoint2 = oldCurve.GetEndPoint(1);
			if (oldCurve.GetType() == typeof(Line))
			{
				XYZ startPoint = new XYZ(hyendPoint.X, hyendPoint.Y, dElevation);
				XYZ endPoint = new XYZ(hyendPoint2.X, hyendPoint2.Y, dElevation);
				result = YJKLineEx.YJKGetBound(startPoint, endPoint);
			}
			else if (oldCurve.GetType() == typeof(Arc))
			{
				XYZ xyz = Geometry.CalculatMidPoint(oldCurve as Arc);
				XYZ startPnt = new XYZ(hyendPoint.X, hyendPoint.Y, dElevation);
				XYZ endPnt = new XYZ(hyendPoint2.X, hyendPoint2.Y, dElevation);
				XYZ radianPnt = new XYZ(xyz.X, xyz.Y, dElevation);
				result = this.mUIApp.Application.CreatYJKArc(startPnt, endPnt, radianPnt);
			}
			return result;
		}

		private bool IsPointAtCurveLeft(Curve curve, XYZ ptCheck)
		{
			XYZ hyendPoint = curve.GetEndPoint(0);
			XYZ hyendPoint2 = curve.GetEndPoint(1);
			XYZ xyz = new XYZ(ptCheck.X, ptCheck.Y, hyendPoint.Z);
			if (curve.GetType() == typeof(Line))
			{
				return Geometry.PointAtLineLeft(xyz, hyendPoint, hyendPoint2);
			}
			if (!(curve.GetType() == typeof(Arc)))
			{
				return false;
			}
			Arc arc = curve as Arc;
			if (Geometry.PointAtLineLeft(Geometry.CalculatMidPoint(arc), hyendPoint, hyendPoint2))
			{
				return xyz.DistanceTo(arc.Center) > arc.Radius;
			}
			return xyz.DistanceTo(arc.Center) < arc.Radius;
		}

		private List<Curve> OffsetCurves(List<Curve> lstOldCurve, double dOffset, bool bOffsetLeft)
		{
			List<Curve> list = new List<Curve>();
			foreach (Curve oldCurve in lstOldCurve)
			{
				Curve curve = this.OffsetCurve(oldCurve, dOffset, bOffsetLeft);
				if (curve == null)
				{
					return null;
				}
				list.Add(curve);
			}
			List<Curve> list2 = new List<Curve>();
			for (int i = 0; i < list.Count - 1; i++)
			{
				Curve curve2 = list[i];
				Curve curve3 = list[i + 1];
				XYZ xyz = this.ExtenTwoCurveIntersect(curve2, curve3, curve2.GetEndPoint(1));
				if (xyz == null)
				{
					return null;
				}
				Curve item = this.SetCurveEnd(curve2, xyz, 1);
				Curve value = this.SetCurveEnd(curve3, xyz, 0);
				list2.Add(item);
				list[i + 1] = value;
			}
			Curve item2 = list[list.Count - 1];
			list2.Add(item2);
			return list2;
		}

		private Curve OffsetCurve(Curve oldCurve, double dOffset, bool bOffsetLeft)
		{
			XYZ xyz = oldCurve.GetEndPoint(0);
			XYZ xyz2 = oldCurve.GetEndPoint(1);
			Curve result = null;
			if (oldCurve.GetType() == typeof(Line))
			{
				int num = bOffsetLeft ? 1 : -1;
				XYZ xyz3 = xyz2 - xyz;
				xyz3 = Geometry.RotateTo(xyz3, (double)num * Math.PI / 2.0, XYZ.BasisZ);
				xyz += xyz3.Normalize() * dOffset;
				xyz2 += xyz3.Normalize() * dOffset;
				result = YJKLineEx.YJKGetBound(xyz, xyz2);
			}
			else if (oldCurve.GetType() == typeof(Arc))
			{
				Arc arc = oldCurve as Arc;
				XYZ xyz4 = Geometry.CalculatMidPoint(arc);
				double num2 = dOffset;
				if (Geometry.PointAtLineLeft(xyz4, xyz, xyz2))
				{
					if (!bOffsetLeft)
					{
						if (dOffset >= arc.Radius)
						{
							return arc;
						}
						num2 = -dOffset;
					}
				}
				else if (bOffsetLeft)
				{
					if (dOffset >= arc.Radius)
					{
						return arc;
					}
					num2 = -dOffset;
				}
				XYZ xyz5 = xyz - arc.Center;
				XYZ startPnt = xyz + xyz5.Normalize() * num2;
				xyz5 = xyz2 - arc.Center;
				XYZ endPnt = xyz2 + xyz5.Normalize() * num2;
				xyz5 = xyz4 - arc.Center;
				XYZ radianPnt = xyz4 + xyz5.Normalize() * num2;
				result = this.mUIApp.Application.CreatYJKArc(startPnt, endPnt, radianPnt);
			}
			return result;
		}

		private void MergeCurves(List<Curve> lstCurve)
		{
			for (int i = 0; i < lstCurve.Count - 1; i++)
			{
				Curve curve = lstCurve[i];
				for (int j = i + 1; j < lstCurve.Count; j++)
				{
					Curve curve2 = this.MergeCurve(curve, lstCurve[j]);
					if (curve2 != null)
					{
						curve = curve2;
						lstCurve.RemoveAt(j);
						j--;
					}
				}
				lstCurve[i] = curve;
			}
		}

		private Curve MergeCurve(Curve curve1, Curve curve2)
		{
			Curve result = null;
			XYZ hyendPoint = curve1.GetEndPoint(0);
			XYZ hyendPoint2 = curve1.GetEndPoint(1);
			XYZ hyendPoint3 = curve2.GetEndPoint(0);
			XYZ hyendPoint4 = curve2.GetEndPoint(1);
			if (curve1.GetType() == typeof(Line) && curve2.GetType() == typeof(Line))
			{
				XYZ firstVec = hyendPoint2 - hyendPoint;
				XYZ secondVec = hyendPoint4 - hyendPoint3;
				if (GeoUtil.IsParallel(firstVec, secondVec))
				{
					if (hyendPoint.DistanceTo(hyendPoint3) < BalconyManager.precision)
					{
						result = YJKLineEx.YJKGetBound(hyendPoint4, hyendPoint2);
					}
					else if (hyendPoint.DistanceTo(hyendPoint4) < BalconyManager.precision)
					{
						result = YJKLineEx.YJKGetBound(hyendPoint3, hyendPoint2);
					}
					else if (hyendPoint2.DistanceTo(hyendPoint3) < BalconyManager.precision)
					{
						result = YJKLineEx.YJKGetBound(hyendPoint, hyendPoint4);
					}
					else if (hyendPoint2.DistanceTo(hyendPoint4) < BalconyManager.precision)
					{
						result = YJKLineEx.YJKGetBound(hyendPoint, hyendPoint3);
					}
				}
			}
			else if (curve1.GetType() == typeof(Arc) && curve2.GetType() == typeof(Arc))
			{
				Arc arc = curve1 as Arc;
				Arc arc2 = curve2 as Arc;
				if (Math.Abs(arc.Radius - arc2.Radius) < BalconyManager.precision && arc.Center.DistanceTo(arc2.Center) < BalconyManager.precision)
				{
					if (hyendPoint.DistanceTo(hyendPoint3) < BalconyManager.precision)
					{
						result = this.mUIApp.Application.CreatYJKArc(hyendPoint4, hyendPoint2, hyendPoint);
					}
					else if (hyendPoint.DistanceTo(hyendPoint4) < BalconyManager.precision)
					{
						result = this.mUIApp.Application.CreatYJKArc(hyendPoint3, hyendPoint2, hyendPoint);
					}
					else if (hyendPoint2.DistanceTo(hyendPoint3) < BalconyManager.precision)
					{
						result = this.mUIApp.Application.CreatYJKArc(hyendPoint, hyendPoint4, hyendPoint2);
					}
					else if (hyendPoint2.DistanceTo(hyendPoint4) < BalconyManager.precision)
					{
						result = this.mUIApp.Application.CreatYJKArc(hyendPoint, hyendPoint3, hyendPoint2);
					}
				}
			}
			return result;
		}

		private List<Curve> ReverseCurves(List<Curve> lstOldCurve)
		{
			List<Curve> list = new List<Curve>();
			for (int i = lstOldCurve.Count - 1; i >= 0; i--)
			{
				Curve item = this.ReverseCurve(lstOldCurve[i]);
				list.Add(item);
			}
			return list;
		}

		private Curve ReverseCurve(Curve oldCurve)
		{
			XYZ hyendPoint = oldCurve.GetEndPoint(0);
			XYZ hyendPoint2 = oldCurve.GetEndPoint(1);
			Curve result = null;
			if (oldCurve.GetType() == typeof(Line))
			{
				result = YJKLineEx.YJKGetBound(hyendPoint2, hyendPoint);
			}
			else if (oldCurve.GetType() == typeof(Arc))
			{
				XYZ radianPnt = Geometry.CalculatMidPoint(oldCurve as Arc);
				result = this.mUIApp.Application.CreatYJKArc(hyendPoint2, hyendPoint, radianPnt);
			}
			return result;
		}

		private bool TwoCurveEquil(Curve curve1, Curve curve2)
		{
			return !(curve1.GetType() != curve2.GetType()) && curve1.Length == curve2.Length && curve1.GetEndPoint(0).IsAlmostEqualTo(curve2.GetEndPoint(0)) && curve1.GetEndPoint(1).IsAlmostEqualTo(curve2.GetEndPoint(1));
		}

		private XYZ TwoCurveIntersect(Curve curve1, Curve curve2)
		{
			IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
            if ((int)curve1.Intersect(curve2, out intersectionResultArray) == 8 && intersectionResultArray != null && !intersectionResultArray.IsEmpty)
			{
				return intersectionResultArray.get_Item(0).XYZPoint;
			}
			return null;
		}

		private XYZ GetWallEndPoint(Wall wall, int nIndex)
		{
			return (wall.Location as LocationCurve).Curve.GetEndPoint(nIndex);
		}

		private XYZ TwoWallIntersect(Wall wall1, Wall wall2)
		{
			LocationCurve locationCurve = wall1.Location as LocationCurve;
			LocationCurve locationCurve2 = wall2.Location as LocationCurve;
			IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
            if ((int)locationCurve.Curve.Intersect(locationCurve2.Curve, out intersectionResultArray) == 8 && intersectionResultArray != null && !intersectionResultArray.IsEmpty)
			{
				return intersectionResultArray.get_Item(0).XYZPoint;
			}
			return null;
		}

		private bool IsWallInList(Wall element, List<Wall> lstElement)
		{
			foreach (Wall wall in lstElement)
			{
				if (element.Id == wall.Id)
				{
					return true;
				}
			}
			return false;
		}

		private void RedrawDocument(Autodesk.Revit.DB.Document doc)
		{
			Transaction transaction = new Transaction(doc);
			transaction.Start("RedrawElements");
			doc.Regenerate();
			transaction.Commit();
		}

		private XYZ ExtenTwoLineIntersect(XYZ ptS1, XYZ ptE1, XYZ ptS2, XYZ ptE2)
		{
			XYZ result = null;
			Curve curve = YJKLineEx.YJKGetUnBound(ptS1, ptE1 - ptS1);
			Line line = YJKLineEx.YJKGetUnBound(ptS2, ptE2 - ptS2);
			IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
            if ((int)curve.Intersect(line, out intersectionResultArray) == 8 && intersectionResultArray != null && !intersectionResultArray.IsEmpty)
			{
				result = intersectionResultArray.get_Item(0).XYZPoint;
			}
			return result;
		}

		private XYZ ExtenTwoCurveIntersect(Curve curve1, Curve curve2, XYZ ptNearInter)
		{
			XYZ result = null;
			Curve curve3 = null;
			if (curve1.GetType() == typeof(Line))
			{
				curve3 = YJKLineEx.YJKGetUnBound(curve1.GetEndPoint(0), curve1.GetEndPoint(1) - curve1.GetEndPoint(0));
			}
			else if (curve1.GetType() == typeof(Arc))
			{
				Arc arc = curve1 as Arc;
				curve3 = Arc.Create(arc.Center, arc.Radius, 0.0, Math.PI*2, XYZ.BasisX, XYZ.BasisY);
			}
			Curve curve4 = null;
			if (curve2.GetType() == typeof(Line))
			{
				curve4 = YJKLineEx.YJKGetUnBound(curve2.GetEndPoint(0), curve2.GetEndPoint(1) - curve2.GetEndPoint(0));
			}
			else if (curve2.GetType() == typeof(Arc))
			{
				Arc arc2 = curve2 as Arc;
				curve4 = Arc.Create(arc2.Center, arc2.Radius, 0.0, Math.PI*2, XYZ.BasisX, XYZ.BasisY);
			}
			if (curve3 != null && curve4 != null)
			{
				IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
                if ((int)curve3.Intersect(curve4, out intersectionResultArray) == 8 && intersectionResultArray != null && !intersectionResultArray.IsEmpty)
				{
					double num = -1.0;
					for (int i = 0; i < intersectionResultArray.Size; i++)
					{
						XYZ xyzpoint = intersectionResultArray.get_Item(i).XYZPoint;
						double num2 = xyzpoint.DistanceTo(ptNearInter);
						if (num == -1.0 || num > num2)
						{
							num = num2;
							result = xyzpoint;
						}
					}
				}
			}
			return result;
		}

		private void DeleteTempElements()
		{
			Transaction transaction = new Transaction(this.mDoc);
			transaction.Start("delete temp elements");
			foreach (ElementId elementId in this.m_lstTempELementId)
			{
				this.mDoc.Delete(elementId);
			}
			transaction.Commit();
		}

		private List<Wall> SelectLinkWalls(string sPrompt)
		{
			List<Wall> result;
			try
			{
				RevitVersionFuncs.ClearSelection(this.mUIDoc.Selection);
                IEnumerable<Reference> enumerable = this.mUIDoc.Selection.PickObjects((Autodesk.Revit.UI.Selection.ObjectType)1, new YArchitech.Revit.WallFilter(), sPrompt);
				List<Wall> list = new List<Wall>();
				foreach (Reference reference in enumerable)
				{
					Wall wall = this.mDoc.GetElement(reference) as Wall;
					if (wall != null)
					{
						list.Add(wall);
					}
				}
				if (list.Count < 1)
				{
					result = null;
				}
				else if (list.Count == 1)
				{
					result = list;
				}
				else
				{
					foreach (Wall wall2 in list)
					{
						List<Wall> list2 = new List<Wall>();
						List<Wall> list3 = new List<Wall>();
						XYZ wallEndPoint = this.GetWallEndPoint(wall2, 0);
						XYZ wallEndPoint2 = this.GetWallEndPoint(wall2, 1);
						foreach (Wall wall3 in list)
						{
							if (!(wall2.Id == wall3.Id))
							{
								XYZ xyz = this.TwoWallIntersect(wall2, wall3);
								if (xyz != null)
								{
									if (wallEndPoint.DistanceTo(xyz) < BalconyManager.precision)
									{
										list2.Add(wall3);
									}
									else if (wallEndPoint2.DistanceTo(xyz) < BalconyManager.precision)
									{
										list3.Add(wall3);
									}
								}
							}
						}
						if (list2.Count > 1 || list3.Count > 1)
						{
							YJKMessageBox.Show("选择的墙有分叉，不能布置阳台");
							return null;
						}
						if (list2.Count < 1 && list3.Count < 1)
						{
							YJKMessageBox.Show("选择的墙有断开，不能布置阳台");
							return null;
						}
					}
					result = list;
				}
			}
			catch
			{
				result = null;
			}
			return result;
		}

		private bool SelectWall(string prompt, ref Wall wallSelect, ref XYZ ptPick, XYZ ptLast)
		{
			if (ptLast == null)
			{
				return false;
			}
			Line line = null;
			try
			{
				if (this.m_drawJigCurve.DrawJigCurveLine(ref line, ref ptLast, prompt, prompt) != null)
				{
					return false;
				}
			}
			catch (Exception)
			{
				return false;
			}
			if (line == null)
			{
				return false;
			}
			ptPick = line.GetEndPoint(1);
			foreach (Element element in ElementFiltering.FindSpecialElements(this.mDoc, typeof(Wall), BuiltInCategory.OST_Walls))
			{
				Wall wall = element as Wall;
				if (!(wall.LevelId != this.m_BalconyAtlevel.Id) && this.IsPointOnWall(ptPick, wall))
				{
					wallSelect = wall;
					return true;
				}
			}
			YJKMessageBox.Show("点不在墙上");
			return false;
		}

		private bool SelectWall(string prompt, ref Wall wallSelect, ref XYZ ptPick)
		{
			ptPick = this.PickPoint(prompt);
			if (ptPick == null)
			{
				return false;
			}
			foreach (Element element in ElementFiltering.FindSpecialElements(this.mDoc, typeof(Wall), BuiltInCategory.OST_Walls))
			{
				Wall wall = element as Wall;
				if (!(wall.LevelId != this.m_BalconyAtlevel.Id) && this.IsPointOnWall(ptPick, wall))
				{
					wallSelect = wall;
					return true;
				}
			}
			YJKMessageBox.Show("点不在墙上");
			return false;
		}

		private bool IsPointOnWall(XYZ pt, Wall wall)
		{
			Curve curve = (wall.Location as LocationCurve).Curve;
			if (curve.GetType() == typeof(Line))
			{
				return this.IsPointOnLineWall(pt, wall);
			}
			return curve.GetType() == typeof(Arc) && this.IsPointOnArcWall(pt, wall);
		}

		private bool IsPointOnLineWall(XYZ pt, Wall wall)
		{
			LocationCurve locationCurve = wall.Location as LocationCurve;
			XYZ hyendPoint = locationCurve.Curve.GetEndPoint(0);
			XYZ hyendPoint2 = locationCurve.Curve.GetEndPoint(1);
			double num = wall.Width / 2.0;
			XYZ xyz = new XYZ(pt.X, pt.Y, hyendPoint.Z);
			XYZ xyz2 = Geometry.CalculateFootPoint(hyendPoint, hyendPoint2, xyz);
			if (xyz.DistanceTo(xyz2) - num > BalconyManager.precision)
			{
				return false;
			}
			if (xyz2.DistanceTo(hyendPoint) < BalconyManager.precision || xyz2.DistanceTo(hyendPoint2) < BalconyManager.precision)
			{
				return true;
			}
			XYZ xyz3 = xyz2 - hyendPoint;
			XYZ xyz4 = hyendPoint2 - xyz2;
			return xyz3.Normalize().IsAlmostEqualTo(xyz4.Normalize());
		}

		private bool IsPointOnArcWall(XYZ pt, Wall wall)
		{
			Arc arc = (wall.Location as LocationCurve).Curve as Arc;
			XYZ center = arc.Center;
			double num = wall.Width / 2.0;
			XYZ xyz = new XYZ(pt.X, pt.Y, center.Z);
			XYZ xyz2 = xyz - center;
			XYZ xyz3 = center + xyz2.Normalize() * arc.Radius;
			if (xyz.DistanceTo(xyz3) - num > BalconyManager.precision)
			{
				return false;
			}
			Line line = YJKLineEx.YJKGetBound(center, xyz3);
            return (int)arc.Intersect(line) == 8;
		}

		private XYZ PickPoint(string sCommandTip)
		{
			try
			{
				return this.mUIDoc.Selection.PickPoint(sCommandTip);
			}
			catch
			{
			}
			return null;
		}

		private XYZ PickPointByBase(string sCommandTip, XYZ ptBase)
		{
			try
			{
				this.DrawCrossFlag(ptBase);
				XLineJig xlineJig = new XLineJig(this.m_uiDoc);
				xlineJig.StartPoint = ptBase;
				XYZ xyz = xlineJig.PickEndPoint(ptBase, sCommandTip);
				xlineJig.Dispose();
				return new XYZ(xyz.X, xyz.Y, ptBase.Z);
			}
			catch
			{
			}
			return null;
		}

		private void DrawCrossFlag(XYZ ptPos)
		{
			Transaction transaction = new Transaction(this.mDoc);
			transaction.Start("DrawCrossFlag");
			double num = AssistFunc.mmToFeet(200.0);
			CurveArray curveArray = new CurveArray();
			Line line = YJKLineEx.YJKGetBound(new XYZ(ptPos.X - num, ptPos.Y + num, 0.0), new XYZ(ptPos.X + num, ptPos.Y - num, 0.0));
			curveArray.Append(line);
			Line line2 = YJKLineEx.YJKGetBound(new XYZ(ptPos.X + num, ptPos.Y + num, 0.0), new XYZ(ptPos.X - num, ptPos.Y - num, 0.0));
			curveArray.Append(line2);
			Autodesk.Revit.DB.View activeView = this.mUIDoc.ActiveView;
			foreach (object obj in this.mDoc.Create.NewDetailCurveArray(activeView, curveArray))
			{
				DetailCurve detailCurve = (DetailCurve)obj;
				if (this.m_LineStyle != null)
				{
					detailCurve.LineStyle = this.m_LineStyle;
				}
				this.m_lstTempELementId.Add(detailCurve.Id);
			}
			transaction.Commit();
		}

		private void DrawTempLine(XYZ ptS, XYZ ptE)
		{
			Transaction transaction = new Transaction(this.mDoc);
			transaction.Start("DrawTempLine");
			AssistFunc.mmToFeet(200.0);
			CurveArray curveArray = new CurveArray();
			Line line = YJKLineEx.YJKGetBound(ptS, ptE);
			curveArray.Append(line);
			Autodesk.Revit.DB.View activeView = this.mUIDoc.ActiveView;
			foreach (object obj in this.mDoc.Create.NewDetailCurveArray(activeView, curveArray))
			{
				DetailCurve detailCurve = (DetailCurve)obj;
				if (this.m_LineStyle != null)
				{
					detailCurve.LineStyle = this.m_LineStyle;
				}
				this.m_lstTempELementId.Add(detailCurve.Id);
			}
			transaction.Commit();
		}

        private void CreateLineType(string name, Autodesk.Revit.DB.Color color)
		{
			Transaction transaction = new Transaction(this.mDoc, "CreateLineType");
			transaction.Start();
			Category category = this.mDoc.Settings.Categories.get_Item(BuiltInCategory.OST_Lines);
			if (!category.SubCategories.Contains(name))
			{
				this.mDoc.Settings.Categories.NewSubcategory(category, name).LineColor = color;
			}
			else
			{
				category.SubCategories.get_Item(name).LineColor = color;
			}
			transaction.Commit();
			foreach (Element element in new FilteredElementCollector(this.mDoc).OfClass(typeof(GraphicsStyle)))
			{
				GraphicsStyle graphicsStyle = element as GraphicsStyle;
				if (graphicsStyle != null && graphicsStyle.Name.CompareTo(name) == 0)
				{
					this.m_LineStyle = graphicsStyle;
					break;
				}
			}
		}

		private void EraseLineType(string name)
		{
			Transaction transaction = new Transaction(this.mDoc, "EraseLineType");
			transaction.Start();
			Category category = this.mDoc.Settings.Categories.get_Item(BuiltInCategory.OST_Lines);
			if (category.SubCategories.Contains(name))
			{
				Category category2 = category.SubCategories.get_Item(name);
				this.mDoc.Delete(category2.Id);
			}
			transaction.Commit();
		}

		private int GetMaxGroupNumber(string sMainGroupName)
		{
			int length = sMainGroupName.Length;
			List<int> list = new List<int>();
			foreach (Element element in new FilteredElementCollector(this.mDoc).OfClass(typeof(Group)).ToElements())
			{
				Group group = element as Group;
				if (group != null)
				{
					string name = group.GroupType.Name;
					int num = name.IndexOf(sMainGroupName);
					if (num != -1)
					{
						string value = name.Substring(num + length, name.Length - num - length);
						int item = 0;
						try
						{
							item = Convert.ToInt32(value);
						}
						catch (Exception)
						{
							continue;
						}
						list.Add(item);
					}
				}
			}
			if (list.Count == 0)
			{
				return 1;
			}
			list.Sort();
			return list[list.Count - 1] + 1;
		}

		private Group CreateGroup(ElementSet elements)
		{
			if (elements.Size < 1)
			{
				return null;
			}
			Group group = RevitVersionFuncs.NewGroup(this.mDoc, elements);
			if (this.m_sGroupName != null && this.m_sGroupName.Length > 0)
			{
				group.GroupType.Name = this.m_sGroupName;
			}
			else
			{
				int maxGroupNumber = this.GetMaxGroupNumber("阳台");
				group.GroupType.Name = "阳台" + maxGroupNumber.ToString();
			}
			return group;
		}

		private Group SelectGroup()
		{
			Group result = null;
			try
			{
				Group group;
				do
				{
                    Reference reference = this.mUIDoc.Selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, new Assist.GroupFilter(), "请选择要编辑的阳台");
					if (reference == null)
					{
						goto IL_53;
					}
					group = (this.mDoc.GetElement(reference) as Group);
				}
				while (!group.Name.Contains("阳台"));
				this.m_sGroupName = group.Name;
				result = group;
				IL_53:;
			}
			catch
			{
			}
			return result;
		}

		private void DrawWallByPoints(List<XYZ> lstWallPt, ref ElementSet newElements)
		{
			for (int i = 0; i < lstWallPt.Count - 1; i++)
			{
				Line line = YJKLineEx.YJKGetBound(lstWallPt[i], lstWallPt[i + 1]);
				Wall wall = RevitVersionFuncs.NewWall(this.mDoc, line, this.m_BalconyWallType, this.m_BalconyAtlevel, this.m_dWallHeight, this.m_dElevation, false, true);
				this.mDoc.Regenerate();
				if (!Geometry.IsEqual(Geometry.RotateTo(line.Direction, Math.PI*.5, XYZ.BasisZ), wall.Orientation))
				{
					wall.Flip();
				}
				newElements.Insert(wall);
			}
		}

		private void DeleteOldBalcony(Group oldBalcony, ref ElementSet baseCurves)
		{
			this.m_lstBaseCurve = new List<ModelCurve>();
			foreach (ElementId elementId in oldBalcony.UngroupMembers())
			{
				Element elementById = this.mDoc.GetElementById(elementId);
				if (elementById != null && elementById.IsValidObject)
				{
					ModelCurve modelCurve = elementById as ModelCurve;
					if (modelCurve != null)
					{
						baseCurves.Insert(modelCurve);
						this.m_lstBaseCurve.Add(modelCurve);
					}
					else
					{
						this.mDoc.Delete(elementId);
					}
				}
			}
		}

		private void WriteBalconyData(ref Group balconyGroup)
		{
			XYZ point = (balconyGroup.Location as LocationPoint).Point;
			Guid guid = new Guid(BalconyManager.m_strXDataGuid);
			Schema schema = Schema.Lookup(guid);
			if (schema == null)
			{
				SchemaBuilder schemaBuilder = new SchemaBuilder(guid);
				schemaBuilder.SetSchemaName("HY_Balcony_XData");
				schemaBuilder.AddSimpleField("BalconyType", typeof(int));
				schemaBuilder.AddSimpleField("GroupPos", typeof(XYZ)).SetUnitType(0);
				schemaBuilder.AddSimpleField("StartPoint", typeof(XYZ)).SetUnitType(0);
				schemaBuilder.AddSimpleField("EndPoint", typeof(XYZ)).SetUnitType(0);
				schemaBuilder.AddSimpleField("ThirdPoint", typeof(XYZ)).SetUnitType(0);
				schemaBuilder.AddSimpleField("WallHeight", typeof(double)).SetUnitType(0);
				schemaBuilder.AddSimpleField("BalconyWidth", typeof(double)).SetUnitType(0);
				schemaBuilder.AddSimpleField("Elevation", typeof(double)).SetUnitType(0);
				schemaBuilder.AddSimpleField("StartId", typeof(ElementId));
				schemaBuilder.AddSimpleField("EndId", typeof(ElementId));
				schemaBuilder.AddSimpleField("WallType", typeof(string));
				schemaBuilder.AddSimpleField("FloorType", typeof(string));
				schema = schemaBuilder.Finish();
			}
			Entity entity = new Entity(schema);
			Field field = schema.GetField("BalconyType");
			entity.Set<int>(field, this.m_nBalconyType);
			Field field2 = schema.GetField("GroupPos");
			entity.Set<XYZ>(field2, point, (Autodesk.Revit.DB.DisplayUnitType)6);
			Field field3 = schema.GetField("StartPoint");
			entity.Set<XYZ>(field3, this.m_ptBalconyStart, (Autodesk.Revit.DB.DisplayUnitType)6);
			Field field4 = schema.GetField("EndPoint");
			entity.Set<XYZ>(field4, this.m_ptBalconyEnd, (Autodesk.Revit.DB.DisplayUnitType)6);
			Field field5 = schema.GetField("ThirdPoint");
			entity.Set<XYZ>(field5, this.m_ptBalconyDir, (Autodesk.Revit.DB.DisplayUnitType)6);
			Field field6 = schema.GetField("WallHeight");
			entity.Set<double>(field6, this.m_dWallHeight, (Autodesk.Revit.DB.DisplayUnitType)6);
			Field field7 = schema.GetField("BalconyWidth");
			entity.Set<double>(field7, this.m_dBalconyWidth, (Autodesk.Revit.DB.DisplayUnitType)6);
			Field field8 = schema.GetField("Elevation");
			entity.Set<double>(field8, this.m_dElevation, (Autodesk.Revit.DB.DisplayUnitType)6);
			Field field9 = schema.GetField("StartId");
			entity.Set<ElementId>(field9, this.m_idElementStart);
			Field field10 = schema.GetField("EndId");
			entity.Set<ElementId>(field10, this.m_idElementEnd);
			Field field11 = schema.GetField("WallType");
			entity.Set<string>(field11, this.m_BalconyWallType.Name);
			Field field12 = schema.GetField("FloorType");
			entity.Set<string>(field12, this.m_BalconyFloorType.Name);
			balconyGroup.SetEntity(entity);
		}

		private bool ReadBalconyData(Group balconyGroup)
		{
			XYZ point = (balconyGroup.Location as LocationPoint).Point;
			Schema schema = Schema.Lookup(new Guid(BalconyManager.m_strXDataGuid));
			Entity entity = balconyGroup.GetEntity(schema);
			if (entity == null || entity.Schema == null)
			{
				return false;
			}
			try
			{
				Field field = schema.GetField("BalconyType");
				this.m_nBalconyType = entity.Get<int>(field);
				field = schema.GetField("GroupPos");
				XYZ xyz = entity.Get<XYZ>(field, (Autodesk.Revit.DB.DisplayUnitType)6);
				field = schema.GetField("StartPoint");
				this.m_ptBalconyStart = entity.Get<XYZ>(field, (Autodesk.Revit.DB.DisplayUnitType)6);
				field = schema.GetField("EndPoint");
				this.m_ptBalconyEnd = entity.Get<XYZ>(field, (Autodesk.Revit.DB.DisplayUnitType)6);
				field = schema.GetField("ThirdPoint");
				this.m_ptBalconyDir = entity.Get<XYZ>(field, (Autodesk.Revit.DB.DisplayUnitType)6);
				field = schema.GetField("WallHeight");
				this.m_dWallHeight = entity.Get<double>(field, (Autodesk.Revit.DB.DisplayUnitType)6);
				field = schema.GetField("BalconyWidth");
				this.m_dBalconyWidth = entity.Get<double>(field, (Autodesk.Revit.DB.DisplayUnitType)6);
				field = schema.GetField("Elevation");
				this.m_dElevation = entity.Get<double>(field, (Autodesk.Revit.DB.DisplayUnitType)6);
				field = schema.GetField("StartId");
				this.m_idElementStart = entity.Get<ElementId>(field);
				field = schema.GetField("EndId");
				this.m_idElementEnd = entity.Get<ElementId>(field);
				field = schema.GetField("WallType");
				string selectTypeStr = entity.Get<string>(field);
				this.m_BalconyWallType = (Helper.GetSelectType<WallType>(this.mDoc, selectTypeStr) as WallType);
				field = schema.GetField("FloorType");
				string selectTypeStr2 = entity.Get<string>(field);
				this.m_BalconyFloorType = (Helper.GetSelectType<FloorType>(this.mDoc, selectTypeStr2) as FloorType);
				XYZ xyz2 = point - xyz;
				if (xyz2.GetLength() > BalconyManager.precision)
				{
					this.m_ptBalconyStart += xyz2;
					this.m_ptBalconyEnd += xyz2;
					this.m_ptBalconyDir += xyz2;
				}
			}
			catch
			{
				return false;
			}
			return true;
		}

		private WallType m_BalconyWallType;

		private FloorType m_BalconyFloorType;

		private double m_dWallHeight;

		private double m_dBalconyWidth;

		private double m_dElevation;

		private bool m_bPickBalconyWidth;

		private Level m_BalconyAtlevel;

		private GraphicsStyle m_LineStyle;

		private List<ElementId> m_lstTempELementId;

        private WindowHandle mWndRevit;

		private UIApplication mUIApp;

		private UIDocument mUIDoc;

		private Document mDoc;

		private XYZ m_ptPickLast;

		private UIDocument m_uiDoc;

		private DrawJigCurve m_drawJigCurve;

		private int m_nBalconyType;

		private XYZ m_ptBalconyStart;

		private XYZ m_ptBalconyEnd;

		private XYZ m_ptBalconyDir;

		private ElementId m_idElementStart;

		private ElementId m_idElementEnd;

		private string m_sGroupName;

		private List<ModelCurve> m_lstBaseCurve;

		private static double precision = 0.001;

		private static string m_strXDataGuid = "6BA3A493-4589-4D54-BFEE-F72086AF37A0";

		private class CurveFilter : ISelectionFilter
		{
			public bool AllowElement(Element elem)
			{
				Type type = elem.GetType();
				return type == typeof(ModelLine) || type == typeof(ModelArc) || type == typeof(DetailLine) || type == typeof(DetailArc);
			}

			public bool AllowReference(Reference reference, XYZ position)
			{
				return false;
			}
		}
	}
}
